package com.shine.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shine.context.SecurityContextHolder;
import com.shine.entity.Menu;
import com.shine.entity.Role;
import com.shine.entity.RoleMenu;
import com.shine.exception.BaseException;
import com.shine.info.RoleInfo;
import com.shine.mapper.RoleMapper;
import com.shine.mapper.RoleMenuMapper;
import com.shine.request.RoleCreateRequest;
import com.shine.request.RoleUpdateRequest;
import com.shine.service.RoleService;
import com.shine.status.ResponseStatus;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author huihui
 * @date 2025/10/16 14:51
 * @description RoleServiceImpl
 */
@Slf4j
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Resource
    private RoleMenuMapper roleMenuMapper;

    @Override
    public List<RoleInfo> listRole() {
        List<Role> roleList = this.list();
        return roleList.stream().map(item -> {
            RoleInfo roleInfo = new RoleInfo();
            BeanUtil.copyProperties(item, roleInfo, true);
            return roleInfo;
        }).toList();
    }

    @Override
    public Boolean deleteById(Long id) {
        if (id == null) {
            throw new BaseException(ResponseStatus.PARAMS_ERROR_MISS_REMOVE_ID);
        }
        return removeById(id);
    }

    @Override
    @Transactional(rollbackFor = BaseException.class)
    public Boolean updateRole(RoleUpdateRequest request) {
        if (request.getId() == null) {
            throw new BaseException(ResponseStatus.PARAMS_ERROR_MISS_UPDATE_ID);
        }
        long count = this.count(
                Wrappers.<Role>lambdaQuery()
                        .eq(Role::getCode, request.getCode())
                        .ne(Role::getId, request.getId())
        );
        if (count > 0) {
            throw new BaseException(ResponseStatus.PARAMS_ERROR_CODE_REPEAT);
        }
        LambdaUpdateWrapper<Role> wrapper = Wrappers.<Role>lambdaUpdate()
                .eq(Role::getId, request.getId())
                .set(Role::getCode, request.getCode())
                .set(Role::getName, request.getName());
        boolean update = this.update(wrapper);
        roleMenuMapper.delete(
                Wrappers.<RoleMenu>lambdaQuery()
                        .eq(RoleMenu::getRoleId, request.getId())
        );
        if (CollectionUtils.isNotEmpty(request.getMenuIdList())) {
            Long userId = SecurityContextHolder.getContext().getPrincipal().getId();
            List<RoleMenu> saveList = request.getMenuIdList().stream().map(item -> {
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(request.getId());
                roleMenu.setMenuId(item);
                roleMenu.setCreateUser(userId);
                roleMenu.setUpdateUser(userId);
                roleMenu.setDeleted(false);
                return roleMenu;
            }).toList();
            roleMenuMapper.saveBatch(saveList);
        }
        return true;
    }

    @Override
    public Boolean saveRole(RoleCreateRequest request) {
        return null;
    }
}